package com.miraclengine.karma;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.andengine.audio.music.Music;
import org.andengine.audio.music.MusicFactory;
import org.andengine.audio.sound.Sound;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.util.FPSLogger;
import org.andengine.extension.texturepacker.opengl.texture.util.texturepacker.TexturePack;
import org.andengine.extension.texturepacker.opengl.texture.util.texturepacker.TexturePackLoader;
import org.andengine.extension.texturepacker.opengl.texture.util.texturepacker.TexturePackTextureRegionLibrary;
import org.andengine.extension.texturepacker.opengl.texture.util.texturepacker.exception.TexturePackParseException;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;

import com.miraclengine.domain.Friend;
import com.miraclengine.kakaolink.KakaoLink;
import com.miraclengine.utils.Debug;
import com.miraclengine.utils.GlobalStatic;
import com.miraclengine.utils.ProgressAsyncTask;
import com.miraclengine.xml.DataRow;
import com.miraclengine.xml.DataTable;
import com.miraclengine.xml.XmlHttpClientHelper;




public class KarmaGame extends SimpleBaseGameActivity {
	
	// ===========================================================
	// Constants
	// ===========================================================

	public static final int CAMERA_WIDTH = 800;
	public static final int CAMERA_HEIGHT = 480;

	// ===========================================================
	// Fields
	// ===========================================================
	
	private String TAG = KarmaGame.class.getSimpleName();
	
	public static KarmaGame instance;
	
	//Camera
	protected Camera mCamera;
	
	private String encoding = "UTF-8";
	
	//Font
	//private Font mFont;
	//private StrokeFont mStrokeFont;
	
	public Scene mCurrentScene;
	
	//public SplashScene splashScene;
	//public LogoScene logoScene;
	public TitleScene titleScene;
	public GameScene gameScene;
	public GameRunningScreen gameRunningScene;
	
	boolean[] isPass = new boolean[5];
	public float mAchieve = 0;
	public int mBookmark = 0;
	public int mTime = 300;
	public long endTime;
	
	public int mFriendNum = 3;
	public int mRequestNum = 2;
	public int mReplyNum = 2;
	
	public List<Friend> listFriend;   
	public List<Friend> rListFriend;
	public List<Friend> replyListFriend;
	
	public Friend myInfo;
	public String myNumber = "00001";
	
	//TexturePacker
	public TexturePack spritesheetTexturePack;
	public TexturePack spritesheetTexturePackModel;
	public TexturePackTextureRegionLibrary mSpritesheetTexturePackTextureRegionLibrary;
	public TexturePackTextureRegionLibrary mSpritesheetTexturePackTextureRegionLibraryModel;
	
	//사운드.
	public Music mBgmMusic;
	public Sound mLogoSound;
	public Sound mButtonSound;
	public Sound mButton1Sound;
	public Sound mCrowdSound;
	public Sound mDingSound;
	public Sound mDoorSound;
	
	
	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public EngineOptions onCreateEngineOptions() {
		// TODO Auto-generated method stub
		mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		
		instance = this;
		
		final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), mCamera);
		
		engineOptions.getAudioOptions().setNeedsMusic(true);
		engineOptions.getAudioOptions().setNeedsSound(true);
		
		return engineOptions;
	}

	@Override
	protected void onCreateResources() {
		// TODO Auto-generated method stub
		
		//텍스쳐 로딩.
		//loading
		try {
			spritesheetTexturePack = new TexturePackLoader(this.getTextureManager(), "gfx/spritesheets/").loadFromAsset(this.getAssets(), "image_data.xml");
			spritesheetTexturePack.loadTexture();
			this.mSpritesheetTexturePackTextureRegionLibrary = spritesheetTexturePack.getTexturePackTextureRegionLibrary();
			
			spritesheetTexturePackModel = new TexturePackLoader(this.getTextureManager(), "gfx/spritesheets/").loadFromAsset(this.getAssets(), "image_model.xml");
			spritesheetTexturePackModel.loadTexture();
			this.mSpritesheetTexturePackTextureRegionLibraryModel = spritesheetTexturePackModel.getTexturePackTextureRegionLibrary();
		} catch(final TexturePackParseException e) {
			Debug.e(TAG, e.toString());
		}
		
		//사운드 로딩.
		MusicFactory.setAssetBasePath("mfx/");
		SoundFactory.setAssetBasePath("mfx/");
		
		try {
			this.mBgmMusic = MusicFactory.createMusicFromAsset(this.mEngine.getMusicManager(), this, "title_bgm1c.mp3");
			this.mBgmMusic.setLooping(true);
			this.mLogoSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "me_logo.ogg");
			this.mButtonSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "button_01.ogg");
			this.mButton1Sound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "page.ogg");
			//this.mButton1Sound.setVolume(0.5f);
			this.mCrowdSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "crowd_01.ogg");
			this.mDingSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "ding_01e.ogg");
			this.mDoorSound = SoundFactory.createSoundFromAsset(this.mEngine.getSoundManager(), this, "door_01.ogg");
		} catch(final IOException e) {
			Debug.e(TAG, e.toString());
		} 
		
		//설정.
		listFriend = new ArrayList<Friend>();
		rListFriend = new ArrayList<Friend>();
		replyListFriend = new ArrayList<Friend>();
	}

	@Override
	protected Scene onCreateScene() {
		// TODO Auto-generated method stub
		
		this.mEngine.registerUpdateHandler(new FPSLogger());
		
		
		if(!isOnline()) {
			this.runOnUiThread(new Runnable() {
				public void run() {
					new AlertDialog.Builder(KarmaGame.this)
			    	.setTitle("알림 " )
			    	.setMessage("네트웍이 연결되지 않았습니다.")
			    	.setCancelable(false)
			    	.setPositiveButton("확인 ", new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							finish();
						}
					}).show();
				}
			});
			
			final Scene scene = new Scene();
			scene.setBackground(new Background(0,0,0));
			return scene;
			
		} else {
			this.runOnUiThread(new Runnable() {
				public void run() {
					new ProgressAsyncTask(mCallBack, new Handler()).execute();
				}
			});
			
			final LogoScene logoScene = new LogoScene(this);
			logoScene.drawScene();
			
			return logoScene;
			
			
		}
		
//		final LogoScene logoScene = new LogoScene(this);
//		logoScene.drawScene();
//		
//		return logoScene;
	} 
	
	
	// ===========================================================
	// Methods
	// ===========================================================
	public void goTitle() {
		if(titleScene == null) {
			this.titleScene = new TitleScene(this);
			this.titleScene.drawScene();
		}
		this.mEngine.setScene(this.titleScene);
	}
	
	public void goGame() {
		this.mEngine.setScene(this.gameScene);
		this.gameScene.updateScene(0, 100, 0);
	}
	
	public void switchGameToRunning(boolean bSwitch, int sceneNumber, int friendNumber, int num) {
		//bSwitch true : game -> running false running -> game
		if(bSwitch) {
			this.mEngine.setScene(this.gameRunningScene);
			this.gameRunningScene.updateScene(sceneNumber, friendNumber, num);
			
		} else {
			this.mEngine.setScene(this.gameScene);
			this.gameScene.updateScene(sceneNumber, friendNumber, num);
		}
		
		if(Settings.musicEnabled) {
			if(this.mBgmMusic.isPlaying()) {
				this.mBgmMusic.pause();
			} else {
				this.mBgmMusic.play();
			}
		}
	}
	
	public boolean isOnline()  {
		ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo nInfo = cm.getActiveNetworkInfo();
		if(nInfo != null && nInfo.isConnectedOrConnecting()) {
			return true;
		}
		return false;
	}
	
	@Override
	public void onBackPressed() {
		// TODO Auto-generated method stub
		
		Debug.d(TAG, "onBackPressed!");
		
		//this.mEngine.
		//super.onBackPressed();
		
		this.runOnUiThread(new Runnable() {
			public void run() {
				new ProgressAsyncTask(mSendCallBack, new Handler()).execute();
			}
		});
	}
	
	private void doMatchData(DataTable dt) {
		String requestIds;
		String[] requestId = null;
		
		String replyIds;
		String[] replyId = null;
		
		int i = 0;
		for(DataRow dr : dt.getRows()) {
			HashMap<String, String> hm = dr.getObject("friend" + i);
			if(hm.get("id").equals(myNumber)) {
				Friend friend = new Friend(dr);
				myInfo = friend;
				
				requestIds = friend.getRequestId();
				if(requestIds != null) {
					requestId = requestIds.split(",");
				}
				
				replyIds = friend.getReplyId();
				if(replyIds != null) {
					replyId = replyIds.split("/");
				}
				
				if(myInfo.getAchieve() != null)
					mAchieve = Float.parseFloat(myInfo.getAchieve());
				mBookmark = 5;
				//if(myInfo.getBookmark() != null)
				//	mBookmark = Integer.parseInt(myInfo.getBookmark());
				if(myInfo.getTime() != null)
					endTime = Long.parseLong(myInfo.getTime());
				
				String temp = myInfo.getPass();
				String[] temp1 = temp.split(",");
				for(int k=0 ; k<5 ; k++) {
					if(temp1[k].equals("0")) {
						isPass[k] = false;
					} else {
						isPass[k] = true;
					}
				}
				
			} else {
				Friend friend = new Friend(dr);
				listFriend.add(friend);
			}
			
			i++;
		}
		
		this.mFriendNum = listFriend.size();
		
		if(requestId != null) {
			for(int j=0 ; j<listFriend.size() ; j++) {
				for(int k=0 ; k<requestId.length ; k++) {
					if(listFriend.get(j).getId().equals(requestId[k])) {
						rListFriend.add(listFriend.get(j));
					}
				}
			}
		}
		
		this.mRequestNum = rListFriend.size();
		
		if(replyId != null) {
			for(int j=0 ; j<listFriend.size() ; j++) {
				for(int k=0 ; k<replyId.length ; k++) {
					String[] temp = replyId[k].split(",");
					if(listFriend.get(j).getId().equals(temp[0])) {
						replyListFriend.add(listFriend.get(j));
					}
				}
			}
		}
		
		this.mReplyNum = replyListFriend.size();
		
		KarmaGame.this.gameScene = new GameScene(KarmaGame.this);
		KarmaGame.this.gameScene.drawScene();
		
		KarmaGame.this.gameRunningScene = new GameRunningScreen(KarmaGame.this);
		KarmaGame.this.gameRunningScene.drawScene();
		
		Debug.d(TAG, "doMatchData");
	}
	
	//통신.
	private ProgressAsyncTask.CallBack mCallBack = new ProgressAsyncTask.CallBack() {
		
		@Override
		public void onPostExecute(DataTable dt) {
			// TODO Auto-generated method stub
			if(GlobalStatic.LAST_EXCUTE_RESULT_CODE.equals("1")) {
				doMatchData(dt);
			} else {
				//Toast.makeText(KarmaGame.this, GlobalStatic.LAST_EXCUTE_RESULT_DESCRIPTION, Toast.LENGTH_SHORT).show();
			}
		}
		
		@Override
		public DataTable doInBackground(String... datas) {
			// TODO Auto-generated method stub
			
			String preUrl = "http://vinchi.miraclengine.com/ServerKarma_Test/proc.php?";
			
			ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
			
			params.add(new BasicNameValuePair("mode", "get"));
			params.add(new BasicNameValuePair("id", myNumber));
			
			DataTable dt = XmlHttpClientHelper.getInstance().execute(preUrl, XmlHttpClientHelper.METHOD.GET, params);
			
			return dt;
		}
	};
	
	private ProgressAsyncTask.CallBack mSendCallBack = new ProgressAsyncTask.CallBack() {
		
		@Override
		public void onPostExecute(DataTable dt) {
			// TODO Auto-generated method stub
			
			//Toast.makeText(KarmaGame.this, GlobalStatic.LAST_EXCUTE_RESULT_DESCRIPTION, Toast.LENGTH_SHORT).show();
			KarmaGame.this.finish();
		}
		
		@Override
		public DataTable doInBackground(String... datas) {
			// TODO Auto-generated method stub
			
			String preUrl = "http://vinchi.miraclengine.com/ServerKarma_Test/proc.php?";
			
			ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
			
			String temp = "";
			
			for(int i=0 ; i<isPass.length ; i++) {
				if(isPass[i]) {
					temp += "1,";
				} else {
					temp += "0,";
				}
			}
			
			params.add(new BasicNameValuePair("mode", "edit"));
			params.add(new BasicNameValuePair("id", myNumber));
			params.add(new BasicNameValuePair("achieve", Integer.toString((int)mAchieve)));
			params.add(new BasicNameValuePair("bookmark", Integer.toString(mBookmark)));
			params.add(new BasicNameValuePair("time", Long.toString(System.currentTimeMillis())));
			params.add(new BasicNameValuePair("pass", temp));
			
			DataTable dt = XmlHttpClientHelper.getInstance().execute(preUrl, XmlHttpClientHelper.METHOD.GET, params);
			
			return dt;
		}
	};
	
	//Kakao
	
	public void sendAppData(String msg) throws NameNotFoundException {
		//카카오 링크 테스트.
		ArrayList<Map<String, String>> metaInfoArray = new ArrayList<Map<String, String>>();
		
		Map<String, String> metaInfoAndroid = new Hashtable<String, String>(1);
		metaInfoAndroid.put("os", "android");
		metaInfoAndroid.put("devicetype", "phone");
		metaInfoAndroid.put("installurl", "market://details?id=com.kakao.talk");
		metaInfoAndroid.put("executeurl", "karmaLinkTest://linkActivity");
		
		// If application is support ios platform.
		Map<String, String> metaInfoIOS = new Hashtable<String, String>(1);
		metaInfoIOS.put("os", "ios");
		metaInfoIOS.put("devicetype", "phone");
		metaInfoIOS.put("installurl", "your iOS app install url");
		metaInfoIOS.put("executeurl", "karmaLinkTest://linkActivity");
		
		// add to array
		metaInfoArray.add(metaInfoAndroid);
		metaInfoArray.add(metaInfoIOS);
		
		// Recommended: Use application context for parameter. 
		KakaoLink kakaoLink = KakaoLink.getLink(this.getApplicationContext());
		
		// check, intent is available.
		if(!kakaoLink.isAvailableIntent()) 
			return;
		
		/**
		 * @param activity
		 * @param url
		 * @param message
		 * @param appId
		 * @param appVer
		 * @param appName
		 * @param encoding
		 * @param metaInfoArray
		 */
		kakaoLink.openKakaoAppLink(
				this, 
				"http://www.miraclengine.com", 
				msg,  
				this.getPackageName(), 
				this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName,
				"신.소.이",
				encoding, 
				metaInfoArray);
	}
}
